package com.tongcao.cn.contoller;

import com.alibaba.common.convert.Convert;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.tongcao.cn.annotation.OperAction;
import com.tongcao.cn.annotation.SysLog;
import com.tongcao.cn.base.req.BookerRequest;
import com.tongcao.cn.base.req.InnerRequest;
import com.tongcao.cn.cache.RedisManager;
import com.tongcao.cn.common.logger.LoggerFactory;
import com.tongcao.cn.common.logger.LoggerMarkers;
import com.tongcao.cn.daiyu.Handler;
import com.tongcao.cn.daiyu.loader.CommandLoader;
import com.tongcao.cn.dfire.result.Result;
import com.tongcao.cn.dfire.result.ResultMap;
import com.tongcao.cn.dfire.utils.ApiResultUtil;
import com.tongcao.cn.domain.bean.EnvironmentMode;
import com.tongcao.cn.domain.bean.ImageProperties;
import com.tongcao.cn.domain.entity.UserEntity;
import com.tongcao.cn.domain.model.APP;
import com.tongcao.cn.domain.model.Person;
import com.tongcao.cn.domain.props.UserProperties;
import com.tongcao.cn.helper.MailHelper;
import com.tongcao.cn.manager.HandlerManager;
import com.tongcao.cn.manager.HttpManager;
import com.tongcao.cn.service.AppInfoService;
import com.tongcao.cn.service.IBookerClientService;
import com.tongcao.cn.service.ISmsService;
import com.tongcao.cn.spring.dpc.Room;
import com.tongcao.cn.thread.ThreadPoolManager;
import com.tongcao.cn.util.DateUtils;
import com.tongcao.cn.util.LoggerUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;

/**
 * @Author:tongcao
 * @Date:2018/8/23 17:52
 * Description:
 */
@Controller
@RequestMapping("test")
@Api
@Slf4j
public class TestController {

    private static final Logger logger = org.slf4j.LoggerFactory.getLogger(TestController.class);

    @Resource
    MailHelper mailHelper;

    @Autowired
    MessageSource messageSource;

    @Resource
    AppInfoService appInfoService;

    @Resource
    RedisManager redisManager;

    @Resource
    HttpManager httpManager;

    @Autowired
    private UserProperties userProperties;

    @Resource
    private Room room;

    private ThreadPoolManager manager = ThreadPoolManager.INSTANCE;

    @Resource
    private ISmsService smsService;

    @Resource
    private HandlerManager handlerManager;

    @Resource
    private IBookerClientService clientService;

    @Resource
    private EnvironmentMode environmentMode;

    @Resource
    private ImageProperties imgUrlProperties;


    public static final String WUXX = "1842781129@qq.com";

    public static final String HY = "503201142@qq.com";

    @GetMapping("/executor")
    @ResponseBody
    public ResultMap executor() {
        BookerRequest request = new BookerRequest();
        request.setName("booker");
        Result result = clientService.execute(request);
        return ApiResultUtil.successResult(result.getModel());
    }

    @GetMapping("/inner")
    @ResponseBody
    public ResultMap executorInner() {
        InnerRequest request = new InnerRequest();
        request.setName("booker");
        Result result = clientService.bizExecute(request);
        return ApiResultUtil.successResult(result.getModel());
    }

    @GetMapping("handler")
    @ResponseBody
    public ResultMap handler(String cmd, HttpServletRequest request) {

        HashMap<String, Object> reponse = Maps.newHashMap();
        Handler handler = CommandLoader.getInstance().getHandler(cmd);
        int result = handler.process(request, Maps.newHashMap(), reponse);

        if (result == 1) {
            return ApiResultUtil.successResult(reponse);
        }
        return ApiResultUtil.successResult(reponse);
    }

    @RequestMapping("/index")
    @OperAction("index")
    public String index(ModelMap map) {
        System.out.println(JSON.toJSONString(room));
        map.addAttribute("host", "http://yo.2dfire.net/#/");
        map.addAttribute("today", DateUtils.format(new Date(), DateUtils.YYMMDD));
        map.addAttribute("img", "http://10.1.28.205/images/img.jpg");
        return "index";
    }

    @RequestMapping("/model")
    @ResponseBody
    public String model(ModelMap map) {
        return environmentMode.getMode();
    }


    @RequestMapping("/getImgLists")
    @ResponseBody
    public ResultMap getUrls(ModelMap map) {
        return ApiResultUtil.successResult(imgUrlProperties.getImgUrls());
    }


    @RequestMapping("/chat")
    @OperAction("chat")
    public String chat(ModelMap map) {
        return "chat";
    }


    @RequestMapping("/log")
    public String log(ModelMap map) {
        return "log";
    }

    @GetMapping("/sendSms")
    @ResponseBody
    public ResultMap sendSms(String mobile, String name) {
        Map<String, Object> params = Maps.newHashMap();
        params.put("mobile", mobile);
        params.put("tpl_value", "#code#=" + name);
        return ApiResultUtil.successResult(smsService.sendSms(params, "GET"));
    }

    /**
     * 异步发送短信
     *
     * @param mobile
     * @param name
     * @return
     */
    @ApiOperation("异步发送短信")
    @GetMapping("/asyncSendSms")
    @ResponseBody
    public ResultMap asyncSendSms(String mobile, String name) {
        Map<String, Object> params = Maps.newHashMap();
        params.put("mobile", mobile);
        params.put("tpl_value", "#code#=" + name);
        smsService.asyncSendSms(params, "GET");
        return ApiResultUtil.successResult("success");
    }

    @RequestMapping("/freemarker")
    public String freemarker(Map<String, Object> map) {
        map.put("name", "Joe");
        //sex:性别，1：男；0：女；
        map.put("sex", 1);

        // 模拟数据
        List<Map<String, Object>> friends = new ArrayList<Map<String, Object>>();
        Map<String, Object> friend = new HashMap<String, Object>();
        friend.put("name", "xbq");
        friend.put("age", 22);
        friends.add(friend);
        friend = new HashMap<String, Object>();
        friend.put("name", "July");
        friend.put("age", 18);
        friends.add(friend);
        map.put("friends", friends);
        return "test";
    }

    @GetMapping("/jumpPage")
    public String jumpToPage(String page) {
        return page;
    }


    @GetMapping("/jumpPageFM")
    public String jumpToPageMesage(ModelMap params) {
        params.put("name", "吴醒醒");
        params.put("songName", "两只大象");
        return "message";
    }


    /**
     * 发送模板邮件
     *
     * @return
     */
    @GetMapping("/sendFM")
    @ResponseBody
    public ResultMap sendFreeMarkerMail() {
        Map<String, String> params = Maps.newHashMap();
        params.put("name", "吴醒醒");
        params.put("songName", "两只老虎");

        mailHelper.sendMessageMail(params, HY, "这是一封测试邮件,别慌!", "message.ftl");
        return ApiResultUtil.successResult("发送模板邮件success");
    }

    /**
     * loggers端点 测试
     *
     * @return
     * @link http://blog.didispace.com/spring-boot-1-5-x-feature-1/
     */
    @GetMapping("/logger")
    public ResultMap getLogger() {
        logger.debug("Logger Level ：DEBUG");
        logger.info("Logger Level ：INFO");
        logger.error("Logger Level ：ERROR");
        return null;
    }

    @SysLog("测试httpclient")
    @RequestMapping("/httpclient")
    public void test(HttpServletResponse response) throws Exception {
        String url = "http://www.baidu.com";
        String str = httpManager.doGet("http://www.baidu.com");
        System.out.println(str);
        response.sendRedirect(url + "?message=hello World&code=200");
    }

    @SysLog("重定向测试")
    @RequestMapping("/redirect")
    public void test2(HttpServletResponse response) throws Exception {
        String url = "http://www.baidu.com";
        String str = httpManager.doGet("http://www.baidu.com");
        System.out.println(str);
        response.sendRedirect("/test/getApp");
    }

    @SysLog("跳转测试")
    @RequestMapping("/forward")
    public void test3(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String url = "http://www.baidu.com";
        String str = httpManager.doGet("http://www.baidu.com");
        System.out.println(str);
//        response.sendRedirect("/test/getApp");
        RequestDispatcher dispatcher = request.getRequestDispatcher("/test/getApp");
        dispatcher.forward(request, response);
    }

    @SysLog("测试hello")
    @ApiOperation("测试hello")
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    @ResponseBody
    public ResultMap test(HttpServletRequest reRquest) {
        System.out.println("测试热部署**************112");
        log.info("测试热部署**************112");
        System.out.println("Header" + JSON.toJSONString(reRquest.getHeaderNames()));
        System.out.println("我是TestContoller test" + JSON.toJSONString(reRquest.getParameterMap()));
        return ApiResultUtil.successResult("hello");
    }

    /**
     * swagger通过注解表明该接口会生成文档，包括接口名、请求方法、参数、返回信息的等等。
     *
     * @param modelMap
     * @return
     * @Api：修饰整个类，描述Controller的作用
     * @ApiOperation：描述一个类的一个方法，或者说一个接口
     * @ApiParam：单个参数描述
     * @ApiModel：用对象来接收参数
     * @ApiProperty：用对象接收参数时，描述对象的一个字段
     * @ApiResponse：HTTP响应其中1个描述
     * @ApiResponses：HTTP响应整体描述
     * @ApiIgnore：使用该注解忽略这个API
     * @ApiError ：发生错误返回的信息
     * @ApiImplicitParam：一个请求参数
     * @ApiImplicitParams：多个请求参数O
     */
    @ApiOperation("测试personMap")
    @RequestMapping(value = "/map", method = RequestMethod.GET)
    @ResponseBody
    public ResultMap testMap(ModelMap modelMap) {
        System.out.println(JSON.toJSONString(modelMap));
        Map<String, String> map = Maps.newHashMap();
        map.put("name", "tongcao");
        map.put("age", "26");
        map.put("address", "浙江省杭州市");
        map.put("id", "120502231");
        String string = JSON.toJSONString(map);
        LoggerUtil.info(LoggerFactory.BUSINESS_LOGGER, LoggerMarkers.BUSINESS, string);
        log.info(string);
        return ApiResultUtil.successResult(map);
    }

    @GetMapping(value = "/person")
    @ApiOperation("测试personMap")
    @ResponseBody
    public ResultMap testPerson(@ApiParam String name, HttpServletResponse response) {
        Person person = new Person();
        person.setAddress("浙江省杭州市拉互助");
        person.setAge(26);
        person.setUserName("huyu");
        person.setLanguage(Lists.newArrayList(Arrays.asList("Java", "C++")));
        return ApiResultUtil.successResult(person);
    }

    @GetMapping(value = "/sendImgMail")
    @ResponseBody
    public ResultMap sendImgMail() {
        CompletableFuture.runAsync(() -> {
            for (int i = 0; i < 10; i++) {
                mailHelper.sendAttachmentsEmail(WUXX, "吴醒醒", "像一棵 海草 海草随波飘摇\n" +
                        "\n" +
                        "海草 海草浪花里舞蹈\n" +
                        "\n" +
                        "海草 海草管它骇浪惊涛我有我乐逍遥\n" +
                        "\n" +
                        "人海啊 茫茫啊随波逐流浮浮沉沉\n" +
                        "\n" +
                        "人生啊如梦啊亲爱的你在哪里\n" +
                        "\n" +
                        "我走过最陡的山路\n" +
                        "\n" +
                        "看过最壮丽的日出\n" +
                        "\n" +
                        "在午夜公路旁\n" +
                        "\n" +
                        "对着夜空说我不服输\n" +
                        "\n" +
                        "押上了性命做赌注\n" +
                        "\n" +
                        "也曾和魔鬼跳过舞\n" +
                        "\n" +
                        "早已看透那些套路\n" +
                        "\n" +
                        "留一点真就足够了\n" +
                        "\n" +
                        "喝过最烈的酒\n" +
                        "\n" +
                        "也泡到过最高傲的妞\n" +
                        "\n" +
                        "随性得像个浪子\n" +
                        "\n" +
                        "也认真得像个傻子\n" +
                        "\n" +
                        "我走过的黑暗与孤独\n" +
                        "\n" +
                        "受过的背叛和无助\n" +
                        "\n" +
                        "却依然参不透这心魔\n" +
                        "\n" +
                        "只学会了率性而活", "D:\\wxx.jpg");
            }
        }, manager.getCorePoolService());
        return ApiResultUtil.successResult("成功发送附件图片");
    }

    @GetMapping(value = "/sendMail")
    @ResponseBody
    public ResultMap sendMail() {

        CompletableFuture.runAsync(() -> {
            for (int i = 0; i < 100; i++) {
                mailHelper.sendSimpleEmail(WUXX, "《夜夜夜夜》", "想问天你在哪里，我想问问我自己，一开始我聪明 结束我聪明\n" +
                        "\n" +
                        "聪明的几乎的毁掉了我自己，想问天问大地，或者是迷信问问宿命\n" +
                        "\n" +
                        "放弃所有 抛下所有，让我飘流在安静的夜夜空里\n" +
                        "\n" +
                        "你也不必牵强再说爱我，反正我的灵魂已片片凋落\n" +
                        "\n" +
                        "慢慢的拼凑，慢慢的拼凑\n" +
                        "\n" +
                        "拼凑成一个完全，不属于真正的我\n" +
                        "\n" +
                        "你也不必牵强再说爱我，反正我的灵魂已片片凋落\n" +
                        "\n" +
                        "慢慢的拼凑，慢慢的拼凑\n" +
                        "\n" +
                        "拼凑成一个完全不属于真正的我\n" +
                        "想问天问大地，或者是迷信问问宿命\n" +
                        "\n" +
                        "放弃所有 抛下所有，让我飘流在安静的夜夜空里\n" +
                        "\n" +
                        "你也不必牵强再说爱我，反正我的灵魂已片片凋落\n" +
                        "\n" +
                        "慢慢的拼凑，慢慢的拼凑\n" +
                        "\n" +
                        "拼凑成一个完全不属于真正的我\n" +
                        "\n" +
                        "你也不必牵强再说爱我，反正我的灵魂已片片凋落\n" +
                        "\n" +
                        "慢慢的拼凑，慢慢的拼凑\n" +
                        "\n" +
                        "拼凑成一个完全不属于真正的我\n" +
                        "\n" +
                        "你也不必牵强再说爱我，反正我的灵魂已片片凋落\n" +
                        "\n" +
                        "慢慢的拼凑，慢慢的拼凑\n" +
                        "\n" +
                        "拼凑成一个完全不属于真正的我\n" +
                        "\n" +
                        "我不愿再放纵，我不愿每天每夜每秒飘流\n" +
                        "\n" +
                        "也不愿 再多问 再多说，再多求我的梦\n" +
                        "\n" +
                        "我不愿再放纵，我不愿每天每夜每秒飘流\n" +
                        "\n" +
                        "也不愿 再多问 再多说，再多求 我的梦", false);
            }
        }, manager.getCorePoolService());


        return ApiResultUtil.successResult("邮件发送成功");
    }

    @ApiOperation("校验user")
    @RequestMapping(value = "/validate", method = RequestMethod.GET)
    public String validate(@Valid UserEntity userEntity, BindingResult result) {
        StringBuilder msg = new StringBuilder();
        if (result.hasErrors()) {
            List<FieldError> fieldErrors = result.getFieldErrors();
            Locale locale = LocaleContextHolder.getLocale();
            for (FieldError error : fieldErrors) {
                //获取国际化错误信息
                String errorMsg = messageSource.getMessage(error, locale);
                msg.append(error.getField() + ":" + errorMsg);
            }
        }
        return msg.toString();
    }


    @SysLog("获取app列表")
    @GetMapping("/getApp")
    @ResponseBody
    public ResultMap getAppInfo(Integer num, Integer size) {
        size = size == null ? 5 : size;
        num = num == null ? 1 : num;
        PageHelper.startPage(num, size);
        List<APP> allApp = appInfoService.getAllApp();
        PageInfo<APP> pageInfo = new PageInfo<>(allApp);
        return ApiResultUtil.successResult(pageInfo.getList());
    }

    @GetMapping("/getApp1")
    @ResponseBody
    public ResultMap getAppInfo1(HttpServletRequest request) {
        Map<String, String[]> parameterMap = request.getParameterMap();
        log.info(JSON.toJSONString(parameterMap));

        StringBuilder sb = new StringBuilder();
        String line = null;
        try {
            BufferedReader reader = request.getReader();
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            log.error(e.getMessage());
        }

        log.info("Stringbuffer reader **************" + sb.toString());
        Integer num = Convert.asInt(request.getParameter("num"));
        Integer size = Convert.asInt(request.getParameter("size"));
        num = num == null ? 1 : num;
        size = size == null ? 5 : size;
        PageHelper.startPage(num, size);
        List<APP> allApp = appInfoService.getAllApp();
        PageInfo<APP> pageInfo = new PageInfo<>(allApp);

        return ApiResultUtil.successResult(pageInfo.getList());
    }

    @SysLog("查询单个app")
    @GetMapping("/app")
    public String app() {
        return JSON.toJSONString(appInfoService.selectByPrimaryKey(1L));
    }

    @GetMapping("setget")
    public ResultMap testRedis(String key, String value) {
        boolean set = redisManager.set(key, value);
        if (set) {
            log.info("redis set success ");
            return ApiResultUtil.successResult("redis set success");
        } else {
            log.info("redis set false ");
            return ApiResultUtil.failResult("redis set fail");
        }
    }

    @GetMapping("/userProps")
    @ResponseBody
    public ResultMap testProps() {
        String username = userProperties.getUsername();
        Integer age = userProperties.getAge();
        String toString = userProperties.getToString();
        log.info(username + "|" + age + "|" + toString);
        return ApiResultUtil.successResult(username + "|" + age + "|" + toString);
    }
}



